package com.geostar.constructionland.attachment.util;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.geostar.constructionland.common.entity.response.ServerResponse;
import com.geostar.constructionland.common.util.CpdetectorEncoding;
import com.geostar.constructionland.common.util.FileUtil;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.multipart.*;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.httpclient.util.EncodingUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@Component
public class MongoDBUtil {
    @Autowired
    ObjectMapper objectMapper;

    /**
     * 带参数的post请求
     * @param url
     * @param params
     * @param files
     * @return
     * @throws Exception
     */
    public ServerResponse doPost(String url, Map<String, String> params, Map<String, String> files) throws Exception {
        PostMethod post = new PostMethod(url);
        post.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET,"utf-8");
        HttpClient client = new HttpClient();
        // 建立连接超时时间. 默认值0表示不设置.
        client.getHttpConnectionManager().getParams().setConnectionTimeout(5 * 1000);//5秒
        //等待数据超时时间. 0表示无限. 此设置在HttpMethodParams没有setSoTimeout(int timeout)时生效.
        client.getHttpConnectionManager().getParams().setSoTimeout(2 * 3600 * 1000);//2小时
        List<Part> partList = new ArrayList<Part>();
        for (Map.Entry<String, String> entry : params.entrySet()) {
            partList.add(new StringPart(entry.getKey(), entry.getValue(), "utf-8"));
        }
        for (Map.Entry<String, String> entry : files.entrySet()) {
            String filePath = entry.getValue();
            checkFile(filePath);
            partList.add(new CustomFilePart(entry.getKey(), new File(filePath)));
        }
        Part[] parts = partList.toArray(new Part[partList.size()]);
        post.setRequestEntity(new MultipartRequestEntity(parts, post.getParams()));
        int status = client.executeMethod(post);
        if (HttpStatus.SC_OK == status) {
            Map<String, LinkedHashMap> responseResultMap = objectMapper.readValue(post.getResponseBodyAsString(), Map.class);
            LinkedHashMap result = responseResultMap.get("result");
            String msg = null;
            if("true".equals(result.get("code").toString())) {
                status = HttpStatus.SC_OK;
                msg = result.get("message").toString();
            }
            LinkedHashMap data = responseResultMap.get("data");
            return new ServerResponse(status, msg, data);
        }
        return new ServerResponse(status, post.getResponseBodyAsString());
    }

    /**
     * 检查文件
     * 若是TXT文件，检查其编码格式，避免乱码
     * @param filePath
     */
    private void checkFile(String filePath) throws IOException {
        File file = new File(filePath);
        if(file.exists()) {
            String fileName = file.getName();
            String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
            if("txt".equals(suffix)) {
                byte[] fileBytes = FileUtil.getBytes(filePath);
                // 获取文件编码
                CpdetectorEncoding cpdetectorEncoding = new CpdetectorEncoding();
                // 获取文件编码
                Charset charsetName = cpdetectorEncoding.getFastEncoding(fileBytes);
                // 避免坐标文件预览乱码
                if(charsetName.name().equals("x-EUC-TW")) {
                    charsetName = Charset.forName("GBK");
                    String fileContent = new String(fileBytes, charsetName);
                    FileUtil.createFile(filePath, fileContent);
                }
            }
        }
    }

    private class CustomFilePart extends FilePart {
        private CustomFilePart(String name, File file) throws FileNotFoundException {
            super(name, file);
        }
        private CustomFilePart(String name, PartSource partSource) {
            super(name, partSource);
        }
        @Override
        protected void sendDispositionHeader(OutputStream out) throws IOException {
            super.sendDispositionHeader(out);
            String filename = getSource().getFileName();
            if (filename != null) {
                out.write(EncodingUtil.getAsciiBytes(FILE_NAME));
                out.write(QUOTE_BYTES);
                out.write(EncodingUtil.getBytes(filename, "utf-8"));
                out.write(QUOTE_BYTES);
            }
        }
    }
}
